----一些公共方法
----#include "..\..\language\LangCode.txt" once
--#include "data\functions\Common\CommonFunc.lua" once				--一些通用方法


----------------背包相关方法的回调处理---------begin---------------------------
ItemAddDispatcher 			= {}					    --获得某一物品的回调
ItemRemoveDispatcher 		= {}					    --失去某一物品的的回调
----------------背包相关方法的回调处理---------end---------------------------

--注册获得某一物品的回调
ItemAddDispatcher.register = function( itemId, proc )
	--print("----->ItemAddDispatcher.register, itemId="..itemId)
	if not proc then
		print("ItemAddDispatcher Register, itemId["..itemId.."]，proc is nil")
	end

	local callTable = ItemAddDispatcher[itemId]
	if not callTable or type(callTable) ~= "table" then
    	ItemAddDispatcher[itemId] = {}
    else
    	for i, itemAddCallProc in ipairs( callTable ) do
    		if itemAddCallProc == proc then
        		return
      		end
    	end
    end
    table.insert( ItemAddDispatcher[itemId], proc )
end

--触发获得道具的方法
ItemAddDispatcher.dispatch = function( sysarg, itemId, itemCount ) 
	--print("----->ItemAddDispatcher.dispatch, itemId="..itemId)
	local callTable = ItemAddDispatcher[itemId]
	if callTable then
		for i, itemAddCallProc in ipairs( callTable ) do
			itemAddCallProc( sysarg, itemId, itemCount )
		end
		return true
	end
	return false
end


--注册失去某一物品的的回调
ItemRemoveDispatcher.register = function( itemId, proc )
	--print("----->ItemRemoveDispatcher.register, itemId="..itemId)
	if not proc then
		print("SceneExitDispatcher Register, itemId["..itemId.."]，proc is nil")
	end

	local callTable = ItemRemoveDispatcher[itemId]
	if not callTable or type(callTable) ~= "table" then
    	ItemRemoveDispatcher[itemId] = {}
    else
    	for i,itemRemoveCallProc in ipairs( callTable ) do
    		if itemRemoveCallProc == proc then
        		return
      		end
    	end
    end
    table.insert( ItemRemoveDispatcher[itemId], proc )
end

--[[触发失去道具的方法
]]
ItemRemoveDispatcher.dispatch = function( sysarg, itemId, itemCount ) 
	--print("----->ItemRemoveDispatcher.dispatch, itemId="..itemId)
	local callTable = ItemRemoveDispatcher[itemId]
	if callTable then
		for i, itemRemoveCallProc in ipairs( callTable ) do
			itemRemoveCallProc( sysarg, itemId, itemCount )
		end
		return true
	end
	return false
end

--给奖励
function GiveCommonAward(sysarg, awards, logId, LogDesc)
	local actorLevel  = Actor.getIntProperty(sysarg,PROP_CREATURE_LEVEL)
	local transAwards = TransAwardsByType( awards, actorLevel )						--需要把经验库经验转化成绝对值经验
	local fAwards = FilterCommonAwards( sysarg, transAwards )   --过滤
	for _, v in ipairs(fAwards) do
		Actor.giveAward(sysarg, v.type, v.id, v.count, v.quality or 0, v.strong or 0, v.bind or 1, 0, logId, LogDesc)
	end
end
--支持sex和job的过滤（sex、job必须要有）
--由于历史遗留问题和客户端处理，现规定，sex=-1,对性别没有要求，job=0, 对职业没有要求
function FilterCommonAward( sysarg, award )
	if award.sex ~= nil and award.sex ~= -1 and award.sex ~= Actor.getIntProperty(sysarg,PROP_ACTOR_SEX) then  --有性别要求
		return nil
	end

	if award.job ~= nil and award.job ~= 0 and award.job ~= Actor.getIntProperty(sysarg, PROP_ACTOR_VOCATION) then --有职业要求
		return nil
	end
	return award
end

--[[
仅针对数值类型
]]
function GetCommonAwardsWithRate( awards, rate )
	local newAwards = DeepCopyFromObject( awards )    		--深度拷贝
	for i, award in ipairs( newAwards ) do
		if award.type > 0 then
			award.count = award.count * rate
		end
	end
	return newAwards
end

--支持sex和job的过滤
function FilterCommonAwardsByCond(Awards, sex, job )
	local fAwards = {}
	for _, award in ipairs( Awards ) do
		local fAward = FilterCommonAwardByCond(award, sex, job)
		if fAward then
			table.insert(fAwards, fAward)
		end
	end
	return fAwards
end

--支持sex和job的过滤（sex、job必须要有）
--由于历史遗留问题和客户端处理，现规定，sex=-1,对性别没有要求，job=0, 对职业没有要求
function FilterCommonAwardByCond( award, sex, job )
	if award.sex and award.sex ~= -1 and sex and sex ~= -1 and award.sex ~= sex then  --有性别要求
		return nil
	end

	if award.job and award.job ~= 0 and job and job ~= 0 and award.job ~= job then --有职业要求
		return nil
	end
	return award
end



--支持sex和job的过滤
function FilterCommonAwards( sysarg, Awards )
	local fAwards = {}
	for _, award in ipairs( Awards ) do
		local fAward = FilterCommonAward(sysarg, award)
		if fAward then
			table.insert(fAwards, fAward)
		end
	end
	return fAwards
end

--给奖励(支持sex和job的过滤)
--由于历史遗留问题和客户端处理，现规定，sex=-1,对性别没有要求，job=0, 对职业没有要求
function GiveCommonAwardEx(sysarg, Awards, logId, LogDesc)
	local actorLevel  = Actor.getIntProperty(sysarg,PROP_CREATURE_LEVEL)
	local transAwards = TransAwardsByType( Awards, actorLevel )						--需要把经验库经验转化成绝对值经验
	local fAwards = FilterCommonAwards( sysarg, transAwards )   --过滤
	for _, v in ipairs(fAwards) do
		--Actor.giveAward(sysarg, v.type, v.id, v.count, v.quality or 0, v.strong or 0, v.bind or 1, 0, logId, LogDesc, v.qualityDataIndex or -1)
		Actor.giveAward(sysarg, v.type, v.id, v.count, v.quality or 0, v.strong or 0, v.bind or 1, 0, logId, LogDesc)
	end
end

--检查背包格子是否足够，返回需要空闲的格子数量(支持sex和job的过滤)
--由于历史遗留问题和客户端处理，现规定，sex=-1,对性别没有要求，job=0, 对职业没有要求
function CheckBagGridForAwardsEx(sysarg, Awards)
	local fAwards = FilterCommonAwards( sysarg, Awards )   --过滤
	local needGirds = 0
	for _, v in ipairs( fAwards ) do
		if v.type == 0 then
			needGirds = needGirds + Item.getAddItemNeedGridCount( sysarg, v.id, v.count, v.quality or 0, v.strong or 0, v.bind or -1)
		end
	end
	local hasEmptyIdxs = Item.getBagEmptyGridCount( sysarg )
	if  hasEmptyIdxs >= needGirds then
		return 0
	else
		return needGirds
	end
end

--检查背包格子是否足够
function IsBagGridEnough(sysarg, awards)
	local fAwards = FilterCommonAwards( sysarg, awards )   --过滤
	local needGirds = 0
	for _, v in ipairs( fAwards ) do
		if v.type == 0 then
			needGirds = needGirds + Item.getAddItemNeedGridCount( sysarg, v.id, v.count, v.quality or 0, v.strong or 0, v.bind or -1)
		end
	end
	local hasEmptyIdxs = Item.getBagEmptyGridCount( sysarg )
	if  hasEmptyIdxs >= needGirds then
		return true
	end
	return false
end

--获取背包格子是否足够
function GetBagGridNeed(sysarg, awards)
	local fAwards = FilterCommonAwards( sysarg, awards )   --过滤
	local needGirds = 0
	for _, v in ipairs( fAwards ) do
		if v.type == 0 then
			needGirds = needGirds + Item.getAddItemNeedGridCount( sysarg, v.id, v.count, v.quality or 0, v.strong or 0, v.bind or -1)
		end
	end
	return needGirds
end

function SendItemTimesUsed(sysarg, itemId)
	--print("SendItemTimesUsed, itemId="..itemId)
	if itemId == 0 then
		SendAllItemsTimesUsed(sysarg)
	else
		SendOneItemTimesUsed(sysarg, itemId)
	end
end

function SendAllItemsTimesUsed(sysarg)
	local netPack = DataPack.allocPacket(sysarg, enBagSystemID, sSendItemTimesUsed)
	if not netPack then
		return
	end

	local itemCount = GetElemsNum( ItemUseCountCfg ) or 0
	DataPack.writeShort(netPack, itemCount)
	--print("SendAllItemsTimesUsed, itemCount="..itemCount)
	for itemId, itemCoungCfg in pairs(ItemUseCountCfg) do
		local maxTimes 	= GetActorDailyMaxTimes( sysarg, enDailyOpTimes_UseItem, itemId )
		local doneTimes	= GetActorDailyDoneTimes( sysarg, enDailyOpTimes_UseItem, itemId )
		local lastTimes = maxTimes - doneTimes
		if lastTimes < 0 then
			lastTimes = 0
		end
		DataPack.writeShort(netPack, itemId)
		DataPack.writeShort(netPack, maxTimes)
		DataPack.writeShort(netPack, lastTimes)
		--print("--->SendAllItemsTimesUsed, itemId="..itemId..", maxTimes="..maxTimes..", lastTimes="..lastTimes)
	end
	DataPack.flush(netPack)
end


function SendOneItemTimesUsed(sysarg, itemId)
	local netPack = DataPack.allocPacket(sysarg, enBagSystemID, sSendItemTimesUsed)
	if not netPack then
		return
	end

	local itemCount = 1
	DataPack.writeShort(netPack, itemCount)
	--print("SendOneItemTimesUsed, itemCount="..itemCount)

	local maxTimes 	= GetActorDailyMaxTimes( sysarg, enDailyOpTimes_UseItem, itemId )
	local doneTimes	= GetActorDailyDoneTimes( sysarg, enDailyOpTimes_UseItem, itemId )
	local lastTimes = maxTimes - doneTimes
	if lastTimes < 0 then
		lastTimes = 0
	end
	DataPack.writeShort(netPack, itemId)
	DataPack.writeShort(netPack, maxTimes)
	DataPack.writeShort(netPack, lastTimes)
	--print("--->SendOneItemTimesUsed, itemId="..itemId..", maxTimes="..maxTimes..", lastTimes="..lastTimes)
	DataPack.flush(netPack)
end

--[[
先判断道具1，不够再判断道具2
]]
function CheckConsumeOneOfTwo( sysarg, item1, item2 )
	if Actor.checkConsume(sysarg, item1.type, item1.id, item1.count, item1.quality or 0, item1.strong or 0, item1.bind or -1)  then
		return true
	end

	if Actor.checkConsume(sysarg, item2.type, item2.id, item2.count, item2.quality or 0, item2.strong or 0, item2.bind or -1)  then
		return true
	end

	Actor.sendItemLack( sysarg, item2.type, item2.id, item2.count )
	return false
end

--[[ 扣除消费，必须先判断 CheckConsumeOneOfTwo
先判断道具1，不够再判断道具2
]]
function DoConsumeOneOfTwo( sysarg, item1, item2, logId, logStr )
	if Actor.removeConsume(sysarg, item1.type, item1.id, item1.count, item1.quality or 0, item1.strong or 0, item1.bind or -1, 0, 
		logId, logStr) >= item1.count then
		return true
	end

	if Actor.removeConsume(sysarg, item2.type, item2.id, item2.count, item2.quality or 0, item2.strong or 0, item2.bind or -1, 0, 
		logId, logStr) >= item2.count then
		return true
	end

	Actor.sendItemLack( sysarg, item2.type, item2.id, item2.count )
	return false
end


--[[
下发批量获得若干奖励的数据
如果玩家一次操作获得若干奖励，可以使用此方法通知客户端
]]
function CommonSendAwardsGotten( sysarg, awards )
	local netPack = DataPack.allocPacket(sysarg, enBagSystemID, sCommonSendAwardsGotten)
	if not netPack then
		return
	end

	local count = #awards
	DataPack.writeByte(netPack, count)
	--print("SendAllItemsTimesUsed, itemCount="..itemCount)
	for i, award in pairs( awards or {} ) do
		DataPack.writeByte(netPack, award.type)
		DataPack.writeInt(netPack, award.id)
		DataPack.writeUInt(netPack, award.count)
		--print("CommonSendAwardsGotten, type="..award.type..", id="..award.id..", count="..award.count)
	end
	DataPack.flush(netPack)
end
